package com.mjk.manager.gen.work;

import com.mjk.common.base.error.BeeError;
import com.mjk.common.base.model.BaseEntity;
import com.mjk.common.base.response.BeeResponse;
import com.mjk.common.base.work.BaseWork;
import com.mjk.common.base.work.annotation.BeeApi;
import com.mjk.common.base.work.annotation.BeeWork;
import com.mjk.common.core.jdbc.annotation.ArcSharding;
import com.mjk.common.core.jdbc.service.plus.idbservice.BeeDBService;
import com.mjk.common.core.jdbc.service.plus.wrap.BeeQueryWrapper;
import com.mjk.common.core.jdbc.util.TableUtils;
import com.mjk.common.tools.springextend.BeeApplicationListener;
import com.mjk.common.util.*;
import com.mjk.manager.gen.dto.GenDto;
import com.mjk.manager.usercenter.model.ScGenConfModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * scui 界面生成
 * @author Administrator
 *
 */
	@BeeWork(work = "scuigen")
public class ScuiGenerateWork extends BaseWork implements BeeApplicationListener {
	@Autowired
	private BeeDBService beeDBService;
	
	@Autowired
	private GenWork gen;
	
	@Autowired
	private RedisTemplate redisTemplate;
	
	@Value(value="${sharding.jdbc.datasource.defaultname}")
	private String DEFAULT_NAME;
	
	private final List<GenDto> genBeans = new ArrayList<>();
	
	private  String MENU_GEN_KEY = "menu_gen";
	/**
	 * 获取可生成得scui 列表
     */
	@BeeApi(name = "获取可生成的列表")
	public BeeResponse getScuiGenerateList(GenDto dto) {
		List<GenDto> gens = genBeans;
		if(ObjectUtils.isNotEmpty(dto.getEntityName())) {
			gens = genBeans.stream().filter(bean->bean.getEntityName().contains(dto.getEntityName())).collect(Collectors.toList());
		}
		//查询所有的配置信息
		BeeQueryWrapper wrapper = new BeeQueryWrapper(new ScGenConfModel());
		List<ScGenConfModel> confs = beeDBService.findManyByWrapper(wrapper);
		Map<String,ScGenConfModel> confMap = confs.stream().collect(Collectors.toMap(ScGenConfModel::getTableName, Function.identity(), (key1, key2) -> key2));
		//查询所有的菜单信息
//		BeeQueryWrapper menWrapper = new BeeQueryWrapper(new ScMenuModel());
//		List<ScMenuModel> menus = beeDBService.findManyByWrapper(menWrapper);
//		Map<String,ScMenuModel> menuMap =menus.stream().collect(Collectors.toMap(ScMenuModel::getComponent, Function.identity(), (key1, key2) -> key2));
		for(GenDto gen1 : gens) {
			ScGenConfModel conf = confMap.get(gen1.getTabName());
			if(null != conf){
				//服务路径
				String name = getTableName(gen1.getEntity());
				String serverPath = conf.getServiceProjectPath()+conf.getServicePath()+name+"\\"+ StrUtils.toUpperCaseFirstOne(name) + "WorkProxy.java";
				if(FileUtils.exist(serverPath)){
					gen1.setServerExit("1");
				}
				String viewPath = conf.getWebProjectPath()+conf.getWebPath()+name+"\\"+"index.vue";
				if(FileUtils.exist(viewPath)){
					gen1.setViewExit("1");
				}
//				if(menuMap.containsKey(name.toLowerCase())){
//					gen1.setMenuExit("1");
//				}
			}

		}
		return BeeError.BEE_SUC.tranceError(gens);
	}
	/**
	 * 获取scui 配置信息
     */
	public BeeResponse getScuiConf(GenDto dto) {
		ScGenConfModel conf =  getGenConf(dto);
        return BeeError.BEE_SUC.tranceError(conf);
	}
	/**
	 * 保存或者修改配置信息
     */
	public BeeResponse saveScuiConf(ScGenConfModel model) {
		BeeQueryWrapper wrapper = new BeeQueryWrapper(model);
		wrapper.eq(ScGenConfModel::getTableName,model.getTableName());
		List<ScGenConfModel> confs = beeDBService.findManyByWrapper(wrapper);
		if(CollectionUtils.isEmpty(confs)){
			//需要插入
			model.setId(null);
			beeDBService.insert(model);
		}else{
			beeDBService.update(wrapper);
		}
		return BeeError.BEE_SUC.tranceError();
	}
	/**
	 * 保存Sc代码生成配置
     */
	public BeeResponse genCode(GenDto dto) {
		Map<String,GenDto> map = TransfromUtils.toMap(genBeans, "entityName");
		dto.setEntity(map.get(dto.getEntityName()).getEntity());
		//获取生成路径
		ScGenConfModel conf =  getGenConf(dto);
		if(null == conf){
			return BeeError.SYSTEM_GEN_CONF_IS_NULL.tranceError();
		}
		BeanUtils.copyProperties(conf,dto);
		gen.doUiGen(dto);
		return BeeError.BEE_SUC.tranceError();
	}
	private ScGenConfModel getGenConf(GenDto dto){
		BeeQueryWrapper wrapper = new BeeQueryWrapper(new ScGenConfModel());
		wrapper.condition("table_name=#{1} or table_name=#{2} ",dto.getTabName(),"all");
		List<ScGenConfModel> confs = beeDBService.findManyByWrapper(wrapper);
		ScGenConfModel conf =  null;
		if(!CollectionUtils.isEmpty(confs)){
			if(confs.size()>1){
				conf = confs.stream().filter(item->item.getTableName().equals(dto.getTabName())).findFirst().get();
			}else{
				conf = confs.get(0);
			}
		}
		return conf;
	}
	private String getTableName(BaseEntity model) {
		String tableName = TableUtils.getTableName(model);
		if (tableName.contains("_")) {
			tableName = StrUtils.underlineToHump(tableName);
		}
		return tableName;
	}
	@Override
	public void doApplicationEvent(ContextRefreshedEvent event) {
		Map<String, BaseEntity> genBeanMap = event.getApplicationContext().getBeansOfType(BaseEntity.class);
		for(Entry<String,BaseEntity> entry: genBeanMap.entrySet()) {
			ArcSharding sharding = Objects.requireNonNull(AopTargetUtils.getTarget(entry.getValue())).getClass().getAnnotation(ArcSharding.class);
			if(null!=sharding) {
				GenDto gen1 = new GenDto();
				gen1.setEntityName(entry.getValue().getClass().getName());
				gen1.setDbName(ObjectUtils.isEmpty(sharding.dataSource())?DEFAULT_NAME:sharding.dataSource());
				gen1.setTabName(sharding.table());
				gen1.setEntity(entry.getValue());
				this.genBeans.add(gen1);
			}
		}
	}
}
